//== SAGITTARIUS ============================================================================

//== FILEDOC =========================================================================

/** @file hashtable_th.h
  * @brief Thread-safe hash table
  */

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__HASHTABLE_TH__H_
#define __SAGUTTARUIS__HASHTABLE_TH__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/parallel/multisema.h"
#include <stddef.h>

#define HASH_COLLISION 1
#define HASH_SUCCESS   0

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    uint64 k;
    void* v;
    size_t len;
} hashkv_pair64;

//hashkv_pair makehashkv_pair64(void* p, size_t len);

typedef struct {
    uint32 n;
    uint32 depth;
    hashkv_pair64* e;
    SG_DEF_MULTISEMA(sema);
} hashbucket64;

typedef struct {
    uint64 nbuckets;
    hashbucket64* buckets;
    SG_DEF_MULTISEMA(sema);
} hashtable64; //Just like my Nintendo...

void* _ht64_get(hashtable64* ht, hashkv_pair64 e);
void* ht64_get(hashtable64* ht, void* p, size_t len);

int _ht64_check(hashtable64* ht, hashkv_pair64 e);
int ht64_check(hashtable64* ht, void* p, size_t len);

int _ht64_insert(hashtable64* ht, hashkv_pair64 e);
int ht64_insert(hashtable64* ht, void* p, size_t len, size_t copy_len);

hashtable64* ht64_rehash(hashtable64* ht, uint32 nbuckets, uint32 depth);

//hashtable* create_hashtable(uint32 nbuckets, uint32 depth);

void ht64_destroy(hashtable64* h);

void ht64_dumpstate(int fd, hashtable64* h);

#ifdef __cplusplus
}//extern "C"
#endif

#endif
